package com.qhgrain.app.service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.paas.base.modules.utils.lang.StringUtil;
import com.qhgrain.app.constant.AppEnum;
import com.qhgrain.app.constant.UrlEnum;
import com.qhgrain.app.util.ConfigUtil;
import com.qhgrain.app.vo.AppVo;
import com.qhgrain.app.vo.RoleUnitVo;
import com.qhgrain.app.vo.Unit;
import com.qhgrain.app.vo.UnitVo;
import com.qhgrain.gway.util.HttpUtil;
import com.sun.star.uno.RuntimeException;

@Service
public class UnitService {

	private static Logger LOG = LoggerFactory.getLogger(UnitService.class);

	private final static String BASE_URL = ConfigUtil.getProperties(UrlEnum.UNIT)+"/iunitservice";

	@Autowired
	private ApplicationService applicationService;
	/**
	 * 获取所有机构列表
	 * 2016年4月6日 上午10:48:04
	 * 
	 * @tags
	 * @author zhaoyq
	 */
	public List<Unit> getAllUnit() throws Exception {
		Map<String, Object> map = new HashMap<String, Object>();
		String vo = HttpUtil.postFormParams(BASE_URL,"/queryUnit", map);
		JSONObject voJson = JSONObject.parseObject(vo);
		if ("1".equals(voJson.getString("state"))) {
			return JSONArray.parseArray(voJson.getString("data"), Unit.class);
		} else {
			LOG.error("从api获取组织机构数据失败..." + vo);
			throw new RuntimeException("从api获取组织机构数据失败");
		}

	}
	/**
	 * 
	 * @param roleId
	 * @param appId
	 * @param unitList [{"id"}]
	 * @throws IOException 
	 */
	public String saveRoleUnit(RoleUnitVo roleUnitVo) throws IOException{
		if(roleUnitVo == null || StringUtil.isBlank(roleUnitVo.getRoleId()) || StringUtil.isBlank(roleUnitVo.getAppId())){
			throw new RuntimeException("roleId/appId不能为空");
		}
		
		Map<String,Object> map = new HashMap<String,Object>();
		map.put("roleId", roleUnitVo.getRoleId());
		map.put("appId", roleUnitVo.getAppId());
		map.put("unitList", JSON.toJSON(roleUnitVo.getUnitList()).toString());
		
		String vo = HttpUtil.post(BASE_URL+"/saveRoleUnits", map);
		JSONObject voJson = JSONObject.parseObject(vo);
		if("1".equals(voJson.getString("state"))){
			return voJson.getString("data");
		}else{
			throw new RuntimeException("保存角色-应用-组织，api出错...vo="+vo);
		}
	}
	
	/**
	 * 根据角色、应用获取组织
	 * @param roleId
	 * @param appId
	 * @return
	 * @throws IOException
	 */
	public RoleUnitVo getRoleUnitByRole(String roleId,String appId) throws IOException{
			
		if(StringUtil.isBlank(roleId) || StringUtil.isBlank(appId)){
			throw new RuntimeException("roleId和appId不能为空");
		}
		
		Map<String,String> map = new HashMap<String,String>();
		map.put("roleId", roleId);
		map.put("appId", appId);
		
		String vo = HttpUtil.get(BASE_URL+"/getRoleUnitByRole", map);
		JSONObject voJson = JSONObject.parseObject(vo);
		if("1".equals(voJson.getString("state"))){
			if(StringUtil.isNotBlank(voJson.getString("data"))){
				RoleUnitVo ru = new RoleUnitVo();
				JSONObject data = voJson.getJSONObject("data");
				ru.setRoleId(data.getString("roleId"));
				ru.setAppId(data.getString("appId"));
				if(StringUtil.isNotBlank(data.getString("unitList"))){
					ru.setUnitList(JSONArray.parseArray(data.getString("unitList"), UnitVo.class));
				}
				
				return ru;
			}
			return null;
		}else{
			throw new RuntimeException("从api获取角色-组织关联失败...map="+map+"....vo="+vo);
		}
		
	}
	/**
	 * 根据用户、应用获取组织
	 * @param roleId
	 * @param appId
	 * @return
	 * @throws IOException
	 */
	public RoleUnitVo getRoleUnitByUser(String userId,String appId) throws IOException{
			
		if(StringUtil.isBlank(userId) || StringUtil.isBlank(appId)){
			throw new RuntimeException("roleId和appId不能为空");
		}
		
		Map<String,String> map = new HashMap<String,String>();
		map.put("userId", userId);
		map.put("appId", appId);
		
		String vo = HttpUtil.get(BASE_URL+"/getRoleUnitByUser", map);
		JSONObject voJson = JSONObject.parseObject(vo);
		if("1".equals(voJson.getString("state"))){
			//用户-角色-应用，可能用户有多个角色，且都有同一个应用，则把这多个同应用的组织进行合并和去重复
			//直接转，报错了
		//	List<RoleUnitVo> list = JSONObject.parseArray(voJson.getJSONArray("data").toJSONString(), RoleUnitVo.class);
			
			List<RoleUnitVo> list = new ArrayList<RoleUnitVo>();
			JSONArray array = voJson.getJSONArray("data");
			
			if(array != null && array.size() > 0 ){
				RoleUnitVo t = null;
				JSONObject o = null;
				for(int i = 0;i<array.size();i++){
					o = array.getJSONObject(i);
					t = new RoleUnitVo();
					t.setRoleId(o.getString("roleId"));
					t.setAppId(o.getString("appId"));
					if(StringUtil.isNotBlank(o.getString("unitList"))){
						t.setUnitList(JSONArray.parseArray(o.getString("unitList"), UnitVo.class));
					}
					
					list.add(t);
				}
			}
			
			if(list == null || list.size() == 0) return null;
			List<UnitVo> unitList = new ArrayList<UnitVo>();
			for(RoleUnitVo v : list){
				if(v.getUnitList() != null ){
					unitList.addAll(v.getUnitList());
				}
			}
			//临时记录unitId，筛选unit,去重复
			Set<String> unitIds = new HashSet<String>();
			List<UnitVo> unitList2 = new ArrayList<UnitVo>();
			for(UnitVo v : unitList){
				if(unitIds.add(v.getId())){
					unitList2.add(v);
				}
			}
			
			RoleUnitVo ruv = list.get(0);
			ruv.setUnitList(unitList2);
			return ruv;
		}else{
			throw new RuntimeException("从api获取角色-组织关联失败...map="+map+"....vo="+vo);
		}
		
	}
	
	public Unit findByUnitId(String unitId) throws IOException{
		if(StringUtils.isBlank(unitId)){
			throw new RuntimeException("unitId不能为空");
		}
		Map<String,String> map = new HashMap<String,String>();
		map.put("unitId", unitId);
		String vo = HttpUtil.get(BASE_URL+"/getUnitById",map);
		JSONObject voJson = JSONObject.parseObject(vo);
		if("1".equals(voJson.getString("state"))){
			return JSONObject.parseObject(voJson.getString("data"), Unit.class);
		}else{
			throw new RuntimeException("根据unitId从api获取数据失败...map="+map+"....vo="+vo);
		}
	}
	/**
	 *获取组织数据，给业务角色授权用的组织数据
	 * @param appId
	 * @return
	 * @throws IOException 
	 */
	public List<Unit> getUnitsForRoleGrant(String appId) throws Exception{
		AppVo app = this.applicationService.find(appId);
		if(app == null){
			throw new RuntimeException("获取不到app的信息....appId="+appId);
		}
		String dataFromUrl = ConfigUtil.getProperties("unit_"+app.getAppCode());
		if(StringUtil.isBlank(dataFromUrl)){
			//如果是空的，没有指定来源，则使用本地的
			return getAllUnit();
		}else if(AppEnum.DANG_YUAN_GUAN_LI.getCode().equals(app.getAppCode())
						 || AppEnum.DANG_ZU_ZI_HUO_DONG_GUAN_LI.getCode().equals(app.getAppCode())
						 || AppEnum.REN_WU_GUAN_LI.getCode().equals(app.getAppCode())){
			return getDangUnit(dataFromUrl);
		}else{
			throw new RuntimeException("未知的unit数据来源....dataFromUrl="+dataFromUrl);
		}
	}
	/**
	 * "id": "dgov00004f13cd81a2cf44a082fbb6baa87edecb",
    "orgCode": null,
    "orgParentId": "0",
    "orgName": "省粮食局党组",
    "level": "0",
    "path": null,
    "namePath": null,
    "createId": "100",
    "createName": "ZCS",
    "createDate": 1451618092000,
    "modifyId": null,
    "modifyDate": null,
    "isLast": "",
    "isUnit": "Y",
    "orgOrder": 1,
    "status": 0  

	 * @param url
	 * @return
	 * @throws Exception
	 */
	private List<Unit> getDangUnit(String url) throws Exception{
		String data = HttpUtil.get(url);
		List<Unit> list = new ArrayList<Unit>();
		if(StringUtils.isNotBlank(data)){
			JSONArray array = JSONArray.parseArray(data);
			if(array != null){
				Unit u = null;
				JSONObject o = null;
				for(int i = 0; i < array.size() ; i++){
					o = array.getJSONObject(i);
					u = new Unit();
					u.setUnitId(o.getString("id"));
					u.setParentId(o.getString("orgParentId"));
					u.setUnitName(o.getString("orgName"));
					
					list.add(u);
				}
			}
		}
		
		return list;
	}
}
